<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>JSON 3 Unit Tests</title>
    <link rel="stylesheet" href="../node_modules/spec/src/newton.css" media="screen">
    <script src="../node_modules/spec/lib/spec.js"></script>
    <script src="../node_modules/spec/lib/newton.js"></script>
    <script>
    var curl, queryParams;
    (function () {
      if (!(typeof Spec == "object" && Spec || typeof Newton == "object" && Newton)) {
        return;
      }

      queryParams = Newton.parseQuery(location.search);
      if (Spec.hasKey(queryParams, "amd")) {
        // Load RequireJS or `curl.js`. `document.write` is used because older
        // versions of Safari and Chrome do not support DOM script injection.
        curl = { "apiName": "require" };
        document.write('<script src="../node_modules/' + (queryParams.amd == "require" ? "requirejs/require" : "curl-amd/dist/curl/curl") + '.js"><\/script>');
      }

      if (Spec.hasKey(queryParams, "prototype")) {
        document.write('<script src="../vendor/prototype.js"><\/script>');
      }
    }());
    </script>
    <script>
    var initSauceLabs = function () {};

    (function () {
      if (!(typeof Spec == "object" && Spec || typeof Newton == "object" && Newton)) {
	return;
      }

      if (queryParams && Spec.hasKey(queryParams, "saucelabs")) {
        var test_results = {
              "passed": 0,
              "failed": 0,
              "total": 0,
              "duration": 0,
              "tests": []
            },
            startTime, endTime, testStartTime, testEndTime;

        initSauceLabs = function (testSuite) {
          testSuite.on("all", function (event) {
            switch (event.type) {
              case "start":
                startTime = testStartTime = new Date();
                break;
              case "assertion":
                // testEndTime = new Date();
                // test_results.total++;
                // test_results.passed++;
                // test_results.tests.push({
                //   "name": event.message,
                //   "result": true,
                //   "message": event.message,
                //   "duration": testEndTime - testStartTime
                // });
                testStartTime = new Date(); // testEndTime;
                testEndTime = null;
                break;
              case "failure":
                testEndTime = new Date();
                test_results.total++;
                test_results.failed++;
                test_results.tests.push({
                  "name": event.message,
                  "result": false,
                  "message": event.message,
                  "duration": testEndTime - testStartTime
                });
                testStartTime = testEndTime;
                testEndTime = null;
                break;
              case "complete":
                endTime = new Date();
                test_results.total++;
                test_results.passed++;
                test_results.tests.push({
                  "name": "Tests completed.",
                  "result": true,
                  "message": "Tests completed.",
                  "duration": endTime - testStartTime
                });
                test_results.duration = endTime - startTime;
                window.global_test_results = test_results;
                break;
              default:
                break;
            }
          });
        };
      }
    }());
    </script>
    <script>
    var libraryPath, isAMD, addNoConflictTest;
    (function (root) {
      if (!(typeof Spec == "object" && Spec || typeof Newton == "object" && Newton)) {
        return;
      }

      libraryPath = "../lib/json3" + (Spec.hasKey(queryParams, "minified") ? ".min" : "");

      var previousJSON = root.JSON;
      var previousJSON3 = root.JSON3 = {};

      addNoConflictTest = function (testSuite) {
        testSuite.addTest("`noConflict`", function () {
          var currentJSON3 = root.JSON3;
          this.notStrictEqual(currentJSON3, previousJSON3, "JSON 3 should overwrite the previous value of the `JSON3` object");

          var JSON3 = currentJSON3.noConflict();
          this.strictEqual(root.JSON, previousJSON, "`noConflict` should restore the previous value of the `JSON` object");
          this.strictEqual(currentJSON3, JSON3, "`noConflict` should return the `JSON3` object");
          this.strictEqual(root.JSON3, previousJSON3, "`noConflict` should restore the previous value of the `JSON3` object");

          root.JSON3 = {};
          var noConflictTwice = currentJSON3.noConflict();
          this.strictEqual(noConflictTwice, JSON3, "`noConflict` should return the `JSON3` object when invoked multiple times");
          this.notStrictEqual(root.JSON3, previousJSON3, "`noConflict` should not restore `JSON` and `JSON3` when invoked more than once");

          root.JSON3 = JSON3;
          this.done(6);
        });
      };

      isAMD = typeof require == "function" && typeof define == "function";
      if (!isAMD) {
        document.write('<script src="' + libraryPath + '.js"><\/script>');
        document.write('<script src="test_json3.js"><\/script>');
      }
    }(this));
    </script>
  </head>
  <body>
    <div id="suite"></div>
    <script>
    (function (root) {
      if (!(typeof Spec == "object" && Spec || typeof Newton == "object" && Newton)) {
        return;
      }

      if (isAMD) {
        // Test asynchronous module loading via RequireJS/`curl.js`.
        require({
          // RequireJS accepts relative paths in the module name; `curl.js` does
          // not. Both accept a `paths` map of module paths to relative paths.
          "paths": {
            "json": libraryPath,
            "spec": "../node_modules/spec/lib/spec",
            "newton": "../node_modules/spec/lib/newton"
          },
          // Thwart aggressive resource caching. RequireJS only.
          "urlArgs": "async=" + (+new Date())
        }, ["json", "test_json3"], function (JSON3, testSuite) {
          testSuite.addTest("Asynchronous Module Definition", function (test) {
            test.equal(root.JSON3, JSON3, "The global `JSON3` object should be defined even if JSON 3 is loaded as a module");
            test.equal(JSON3.stringify(1), "1", "JSON 3 should be exported as an asynchronous module");
            test.done(2);
          });
          initSauceLabs(testSuite);
          addNoConflictTest(testSuite);
          testSuite.run();
        });
      } else {
        var testSuite = root.JSON3.testSuite;
        initSauceLabs(testSuite);
        addNoConflictTest(testSuite);
        testSuite.run();
      }
    }(this));
    </script>
  </body>
</html>
